package com.orange.adminapi.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.orange.adminapi.security.handler.AdminAuthenticationSuccessHandler;
import com.orange.adminapi.security.provider.AdminAuthenticationProvider;
import com.orange.core.security.filter.AminAuthenticationFilter;
import com.orange.core.security.handler.AccountAuthenticationFailHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@RequiredArgsConstructor
@Configuration
public class AdminAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

    private final UserDetailsService userDetailsService;
    private final ObjectMapper objectMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    public void configure(HttpSecurity http) {
        AuthenticationSuccessHandler successHandler = new AdminAuthenticationSuccessHandler(objectMapper);
        AuthenticationFailureHandler failHandler = new AccountAuthenticationFailHandler<>(objectMapper);

        AbstractAuthenticationProcessingFilter authenticationFilter = new AminAuthenticationFilter(objectMapper, successHandler, failHandler);
        ProviderManager providerManager = (ProviderManager) http.getSharedObject(AuthenticationManager.class);
        providerManager.setEraseCredentialsAfterAuthentication(false);
        authenticationFilter.setAuthenticationManager(providerManager);

        AuthenticationProvider authenticationProvider = new AdminAuthenticationProvider(userDetailsService, passwordEncoder);

        http.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class).authenticationProvider(authenticationProvider);
    }
}
